package com.ddwl.data.service;


import com.ddwl.common.constant.OperateLogEnum;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.data.dao.OperateLogDao;
import com.ddwl.schema.bo.data.OperateLogBo;
import com.ddwl.data.model.OperateLog;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.data.OperateLogVo;
import com.ddwl.schema.bo.user.UserSearchBo;
import com.ddwl.schema.util.DateUtil;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.order.StatisticsUserVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author hemiaojun
 * @Date 2020/9/17 11:40
 */
@Service
@Slf4j
public class OperateLogService {

    @Resource
    private OperateLogDao operateLogDao;

    @Transactional(rollbackFor = Exception.class)
    public void save(OperateLog operateLog){
        operateLog.setId(UUIDGenerator.getShortUUID());
        operateLogDao.insert(operateLog);
    }

    public OperateLog selectOne(OperateLog operateLog){
        return operateLogDao.selectOne(operateLog);
    }

    public OperateLogVo queryUpdateInviteCode(String userId) {
        OperateLog entity=new OperateLog();
        entity.setUserId(userId);
        entity.setType(OperateLogEnum.typeEnum.UPDATE_INVITE_CODE.getCode());
        return BeanConverUtils.convertBean(selectOne(entity),OperateLogVo.class);
    }

    public Integer countOperateLog(Integer code, String key, String method) {
        return operateLogDao.countOperateLog(code,key,method);
    }

    public PageVo<OperateLogVo> consolePage(PageBo<OperateLogBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        PageInfo<OperateLog> info = new PageInfo<>(operateLogDao.getList(pageBo.getParam()));
        List<OperateLogVo> list = BeanConverUtils.convertBeanList(info.getList(), OperateLogVo.class);
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), list);
    }

    public List<StatisticsUserVo> queryActiveUserCount(UserSearchBo bo) {
        return operateLogDao.queryActiveUserCount(bo);
    }

    public void changeId() {
        PageBo<OperateLogBo> pageBo=createPageBo();
        PageVo<OperateLog> pageVo=getBYPage(pageBo);
        Long total = pageVo.getTotal();
        doChangeId(pageVo.getData());
        int eachSize = pageBo.getPageSize();
        if (total > eachSize) {
            long totalPage = total % eachSize == 0 ? total / eachSize : (total / eachSize) + 1;
            for (int i = 0; i < totalPage-1; i++) {
                pageBo.setPage(i + 2);
                PageVo<OperateLog> pageVo1 =getBYPage(pageBo);
                doChangeId(pageVo1.getData());
            }
        }
    }

    private void doChangeId(List<OperateLog> list) {
        if (!CollectionUtils.isEmpty(list)) {
            Map<String, String> map = new HashMap<>();
            for (OperateLog ol : list) {
                String id = ol.getId();
                if (id.length() == 11) {
                    long longId = UUIDGenerator.reverseShortUUID(id);
                    map.put(id, String.valueOf(longId));
                }
            }
            if (!CollectionUtils.isEmpty(map)) {
                operateLogDao.changeId(map);
            }
        }
    }

    private PageVo<OperateLog> getBYPage(PageBo<OperateLogBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        PageInfo<OperateLog> info = new PageInfo<>(operateLogDao.getListByPage());
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), info.getList());
    }

    private PageBo<OperateLogBo> createPageBo() {
        PageBo<OperateLogBo> pageBo = new PageBo<>();
        pageBo.setPageSize(500);
        pageBo.setAsc(true);
        pageBo.setSort("gmtCreated");
        OperateLogBo bo=new OperateLogBo();
        pageBo.setParam(bo);
        return pageBo;
    }

    public void deleteOperateLog() {
        log.info("delete before 8 days operateLog start");
        Instant date = DateUtil.addDay(Instant.now(), -8);
        operateLogDao.deleteBeforeSpecifyDateOperateLog(date);
        log.info("delete before 8 days operateLog end");
    }

}
